package com.victor9ac.mashup.elasticsearch.aop;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;

import com.victor9ac.mashup.api.MashupDataType;
import com.victor9ac.mashup.elasticsearch.annotation.ES;
import com.victor9ac.mashup.elasticsearch.logic.ElasticSearchBehaviour;

public class ElasticSearchAOP {

	ElasticSearchBehaviour elasticSearchBehaviour;

	public Object indexer(ProceedingJoinPoint pjp) throws Throwable {

		Object aspectResult = null;

		try {

			System.out.println("executing annotation ...");
			
			String keyword = getKeyword(pjp);		
			MashupDataType mashupDataType = getMashupDataType(pjp);

			
			aspectResult = elasticSearchBehaviour.execute(keyword,mashupDataType, pjp);

			System.out.println("exit from annotation ...");

		} catch (Exception e) {
			System.out
					.println(":( ....error executing indexer Elastic annotation ");
			e.printStackTrace();
			aspectResult = pjp.proceed();
		}

		return aspectResult;
	}

	private MashupDataType getMashupDataType(ProceedingJoinPoint pjp)
			throws NoSuchMethodException {
		ES annotation = getAnnotation(pjp, pjp.getSignature());
		MashupDataType mashupDataType = annotation.type();
		return mashupDataType;
	}

	private String getKeyword(ProceedingJoinPoint pjp) throws Throwable {
		String keyword = null;
		Object args[] = pjp.getArgs();
		if (args != null && args.length > 0) {
			keyword = (String) args[0];
		} else {
			pjp.proceed();
		}
		return keyword;

	}

	private ES getAnnotation(ProceedingJoinPoint pjp,
			final Signature signature) throws NoSuchMethodException {
		
		org.aspectj.lang.reflect.MethodSignature msig = (org.aspectj.lang.reflect.MethodSignature)signature;
		
		final String methodName = pjp.getSignature().getName();
		Method method = msig.getMethod();
		ES myAnnotation = null;
		if (method.getDeclaringClass().isInterface()) {

			method = pjp.getTarget().getClass()
					.getDeclaredMethod(methodName, method.getParameterTypes());

		}

		Annotation[] annotations = method.getAnnotations();
		for (Annotation annotation : annotations) {
			if (annotation instanceof ES) {
				myAnnotation = (ES) annotation;

			}
		}
		return myAnnotation;
	}

	public void setElasticSearchBehaviour(
			ElasticSearchBehaviour elasticSearchBehaviour) {
		this.elasticSearchBehaviour = elasticSearchBehaviour;
	}

}
